package swd.base;

import java.io.*;
import java.util.*;

import com.pub.database.*;
import com.pub.tools.*;

public class SwdBase extends SwdConstans{
    protected QueryBean gqbnDAO = null; //不管子類別在那一個package下都可以存取
    protected String gstrPrgKind=null; //程式類型 D--新增 Y--簽核 R--查詢 K--外掛
    protected String gstrGeneratorTemplate = "dotnet"; //預設使用那一版code template
    protected String gstrFramework=".net3.5";
    protected boolean gblnFlowYN=false;
    protected String gstrFlowCode=null;
    //未來若在有public attribute，建議採用setter and getter 減少異動constructor的情況 

    public SwdBase(String pstrGeneratorTemplate,String pstrFramework,QueryBean pqbnDAO) {
        gqbnDAO = pqbnDAO;
        if(pstrGeneratorTemplate!=null && !pstrGeneratorTemplate.trim().equals("")){
        	gstrGeneratorTemplate = pstrGeneratorTemplate;
        }
        if(pstrFramework!=null && !pstrFramework.trim().equals("")){
        	gstrFramework=pstrFramework;
        }
    }
    
    /**
     * 將Entity name轉換成程式碼的命名規則
     * 
     * 程式碼變數命名規則:第一個字母及"_"後的第一個字母大寫，其餘皆為小寫，不可以有底線"_"
     * 
     * @param pstrEntityName Table Name
     * @return
     * @throws Exception
     */
    protected String TransferEntityToCodeName(String pstrEntityName) throws Exception{
    	char[] chrEntityName = pstrEntityName.toCharArray();
    	
    	//若是小寫字母轉成大寫
    	if(chrEntityName[0]>=65){
    		chrEntityName[0] = (char) (chrEntityName[0] - 32);
    	}
    	
    	for(int i=1;i<=chrEntityName.length-1;i++){
    		if(chrEntityName[i]=='_' && i < chrEntityName.length-1){
    			if(chrEntityName[0]>=65){
    				chrEntityName[i+1]=(char) (chrEntityName[i+1] - 32);
    			}
    			i++;
    		}
    	}
    	
    	//將"_"全部拿掉
    	return PublicFunction.replace(String.valueOf(chrEntityName), "_", "", false);
    }

    /**
     * 將field name轉換成程式碼的命名規則
     * 
     * 程式碼變數命名規則:"_"後的第一個字母大寫，其餘皆為小寫，不可以有底線"_"
     * 
     * @param pstrFieldName Field Name
     * @return
     * @throws Exception
     */
    protected String TransferFieldToCodeName(String pstrFieldName) throws Exception{
    	char[] chrEntityName = pstrFieldName.toCharArray();
    	
    	for(int i=1;i<=chrEntityName.length-1;i++){
    		if(chrEntityName[i]=='_' && i < chrEntityName.length-1){
    			if(chrEntityName[0]>=65){
    				chrEntityName[i+1]=(char) (chrEntityName[i+1] - 32);
    			}
    			i++;
    		}
    	}
    	
    	//將"_"全部拿掉
    	return PublicFunction.replace(String.valueOf(chrEntityName), "_", "", false);
    }
    
    /**
     * loadDataFromWKF_INI_FILE
     *
     * @param pstrFldList String
     * @param pstrUserNO String
     * @return ArrayList
     */
    protected ArrayList<Object> loadDataFromWKF_INI_FILE(String pstrFldList, String pstrUserNO) throws
            Exception {
        return (ArrayList<Object>) gqbnDAO.querySQL("select " + pstrFldList +
                                            " from wkf_ini_file where user_no='" +
                                            pstrUserNO + "'").get(0);
    }

    protected String tran_path(String pstrUserNO, String pstrPara, String pstrServer,
                     String pstrPortNO, String pstrSysNO) throws Exception {
        StringBuffer lstbPortNO = new StringBuffer();
        StringBuffer lstbSQL = new StringBuffer();
        Hashtable<String,Hashtable<String,Object>> lhtRunVersion = null;
        String lstrPrgLang = new String();
        String lstrPara = pstrPara;

        try {
            if (pstrPortNO != null && !pstrPortNO.trim().equals("")) {
                lstbPortNO.append(":");
                lstbPortNO.append(pstrPortNO);
            }

            lstbSQL.append(
                    "select runtime_version from wkf_ini_file where user_no='");
            lstbSQL.append(pstrUserNO);
            lstbSQL.append("'");

            lhtRunVersion = gqbnDAO.hashtableSQL(lstbSQL.toString());

            lstrPrgLang = (lhtRunVersion != null &&
                           ((Hashtable<String,Object>) lhtRunVersion.get("0")) != null ?
                           ((Hashtable<String,Object>) lhtRunVersion.get("0")).get(
                                   "RUNTIME_VERSION").toString() : "jsp");

            lstrPara = PublicFunction.replace(lstrPara, "{server}", pstrServer, true);

            lstrPara = PublicFunction.replace(lstrPara, "{sys}", pstrSysNO.toUpperCase(), true);

            lstrPara = PublicFunction.replace(lstrPara, "{port}", pstrPortNO, true);

            lstrPara = PublicFunction.replace(lstrPara, "{prg_lang}",
                                              lstrPrgLang, true);

            return lstrPara;
        } catch (Exception e) {
            throw new Exception(e.toString());
        }
    }

    /**
     * getSysNO
     *
     * @param pstrUserNO String
     * @return String
     */
    public String getSysNO(String pstrUserNO) throws Exception {
        return ((ArrayList<Object>) gqbnDAO.querySQL(
                "select sys_no from wkf_ini_file where user_no='" +
                pstrUserNO + "'").get(0)).get(0).toString();
    }
    /**
     * getFwrPrgNO
     *
     * @param pstrBeanFileName String
     * @param pstrUserNO String
     * @param pstrPrgNO String
     * @return BufferedWriter
     */
    protected BufferedWriter getFwrPrgNO(String pstrBeanFileName,
                                         String pstrOutPathFromFld,
                                         String pstrPackage, String pstrUserNO) throws Exception {

        String lstrMapOutPath = null;
        String lstrRealOutPath = null;

        BufferedWriter lbwrPrgNO = null;

        try {
            lstrMapOutPath = loadDataFromWKF_INI_FILE(pstrOutPathFromFld,
                    pstrUserNO).get(0).toString();

            //"\\com\\swd\\" + getSysNO(pstrUserNO) + "\\" + pstrPrgNO + "\\"
            lstrRealOutPath = tran_path(pstrUserNO, lstrMapOutPath, "", "",
                                        getDefaultSysNO(pstrUserNO)) + pstrPackage;

            if (!(new File(lstrRealOutPath)).isDirectory()) {
                new File(lstrRealOutPath).mkdirs();
            }

            //false代表覆蓋
            /*lbwrPrgNO = new BufferedWriter(new FileWriter(lstrRealOutPath + "\\" +
                    pstrBeanFileName, false));*/

            lbwrPrgNO = new BufferedWriter(new OutputStreamWriter(new
                    FileOutputStream(lstrRealOutPath +
                                     pstrBeanFileName, false), "utf-8"));
        } catch (Exception e) {
            //e.printStackTrace();
            throw new Exception(e.toString());
        }

        return lbwrPrgNO;
    }

    /**
     * getSysNO
     *
     * @param pstrUserNO String
     * @return String
     */
    public String getDefaultSysNO(String pstrUserNO) throws Exception {
        return gqbnDAO.readSingleValueData("select sys_no from wkf_ini_file where user_no='" +
                pstrUserNO + "'");
    }

    protected String tranFieldVar(String pstrTranStr, String pstrPrgNO) throws
            Exception {
        Hashtable<String,Hashtable<String,Object>> lhtFldNO = null;
        String lstrFldNO = null;
        String lstrFrmNO = null;
        String lstrSeqNO = null;
        String lstrTranedStr = pstrTranStr;

        try {
            if (lstrTranedStr.indexOf("{Frs") < 0 &&
                lstrTranedStr.indexOf("{Vrs") < 0) {
                return lstrTranedStr;
            }

            lhtFldNO = gqbnDAO.hashtableSQL(
                    "select fld_no,frm_no,seqno from wkf_frm1 where prg_no='" +
                    pstrPrgNO + "' and exists (select * from wkf_frm0 where wkf_frm0.prg_no=wkf_frm1.prg_no and wkf_frm0.frm_no=wkf_frm1.frm_no and record_kind='S')");

            for (int i = 0; i < lhtFldNO.size(); i++) {
                if (lstrTranedStr.indexOf("{Frs") < 0 &&
                    lstrTranedStr.indexOf("{Vrs") < 0) {
                    break;
                }

                lstrFldNO = ((Hashtable<String,Object>) lhtFldNO.get(String.valueOf(i))).get(
                        "FLD_NO").toString();
                lstrFrmNO = ((Hashtable<String,Object>) lhtFldNO.get(String.valueOf(i))).get(
                        "FRM_NO").toString();
                lstrSeqNO = ((Hashtable<String,Object>) lhtFldNO.get(String.valueOf(i))).get(
                        "SEQNO").toString();

                if (lstrTranedStr.substring(lstrTranedStr.indexOf("{") + 4,
                                            lstrTranedStr.indexOf("}") - 1).
                    equals(lstrFrmNO + lstrSeqNO)) {
                    lstrTranedStr = PublicFunction.replace(lstrTranedStr,
                            (new
                             StringBuffer(lstrTranedStr.substring(lstrTranedStr.
                            indexOf("{"), lstrTranedStr.indexOf("{") + 3))).
                            delete(0, 0).append(lstrFrmNO).append(lstrSeqNO).
                            append("}").toString(),
                            "view.get" + lstrFldNO.substring(0,1).toUpperCase() + lstrFldNO.substring(1) + "()", false);
                }
            }

            return lstrTranedStr;
        } catch (Exception e) {
            e.printStackTrace();
            throw new Exception(e.toString());
        } finally {
            if (lhtFldNO != null) {
                lhtFldNO.clear();
                lhtFldNO = null;
            }
        }
    }

    /**
     * getSimpBeginnerVarType
     *
     * @param pstrVaribleType String
     *
     * @return String
     */
    protected String getSimpBeginnerVarType(String pstrVaribleType) {
        if (pstrVaribleType.toLowerCase().equals("int")) {
            return "int";
        } else if (pstrVaribleType.toLowerCase().equals("long")) {
            return "lng";
        } else if (pstrVaribleType.toLowerCase().equals("double")) {
            return "dbl";
        } else if (pstrVaribleType.toLowerCase().equals("float")) {
            return "flt";
        } else if (pstrVaribleType.toLowerCase().equals("char")) {
            return "chr";
        } else if (pstrVaribleType.toLowerCase().equals("string")) {
            return "str";
        } else if (pstrVaribleType.toLowerCase().equals("boolean")) {
            return "bln";
        }
        return "str";
    }

    protected String tranPublicVar(String pstrTranStr) throws Exception {
        if (pstrTranStr.indexOf("{") < 0 && pstrTranStr.indexOf("&quot;") < 0) {
            return pstrTranStr;
        }

        if (pstrTranStr.toUpperCase().indexOf("{user_id}") >= 0){
            return PublicFunction.replace(pstrTranStr,"{user_id}","view.getLoginUserNO();", true);
        }

        if (pstrTranStr.toUpperCase().indexOf("{seqno}") >= 0){
            return PublicFunction.replace(pstrTranStr,"{seqno}","view.getSeqno();", true);
        }

        if (pstrTranStr.toUpperCase().indexOf("{DATETIME}") >= 0) {
            return PublicFunction.replace(pstrTranStr, "{DATETIME}",
                                          PublicFunction.getSYSDATE(
                                                  "yyyy/MM/dd hh:mi:ss"), true);
        }
        //&quot;
        if (pstrTranStr.indexOf("&quot;") >= 0) {
            return PublicFunction.replace(pstrTranStr, "&quot;","\"", true);
        }
        if (pstrTranStr.toUpperCase().indexOf("{DATE}") >= 0) {
            return PublicFunction.replace(pstrTranStr, "{DATE}",
                                          PublicFunction.
                                          getSYSDATE("yyyy/MM/dd"), true);
        }
        if (pstrTranStr.toUpperCase().indexOf("{YEAR}") >= 0) {
            return PublicFunction.replace(pstrTranStr, "{YEAR}",
                                          PublicFunction.getSYSDATE("yyyy"), true);
        }
        if (pstrTranStr.toUpperCase().indexOf("{MONTH}") >= 0) {
            return PublicFunction.replace(pstrTranStr, "{MONTH}",
                                          PublicFunction.getSYSDATE("MM"), true);
        }
        if (pstrTranStr.toUpperCase().indexOf("{DAY}") >= 0) {
            return PublicFunction.replace(pstrTranStr, "{DAY}",
                                          PublicFunction.getSYSDATE("dd"), true);
        }
        if (pstrTranStr.toUpperCase().indexOf("{HOUR}") >= 0) {
            return PublicFunction.replace(pstrTranStr, "{HOUR}",
                                          PublicFunction.getSYSDATE("hh"), true);
        }
        if (pstrTranStr.toUpperCase().indexOf("{MINUTE}") >= 0) {
            return PublicFunction.replace(pstrTranStr, "{MINUTE}",
                                          PublicFunction.getSYSDATE("mi"), true);
        }
        if (pstrTranStr.toUpperCase().indexOf("{SECOND}") >= 0) {
            return PublicFunction.replace(pstrTranStr, "{SECOND}",
                                          PublicFunction.getSYSDATE("ss"), true);
        }

        return pstrTranStr;

    }

    /**
     * copySWDFile
     *
     * @param pstrInFileName String
     * @param pstrOutFileName String
     */
    public void copySWDFile(String pstrInFileName, String pstrOutFileName) throws
            Exception {
        BufferedInputStream lbisIn = new BufferedInputStream(new
                FileInputStream(pstrInFileName));
        BufferedOutputStream lbosOut = new BufferedOutputStream(new
                FileOutputStream(pstrOutFileName));

        int b;

        while ((b = lbisIn.read()) != -1) {
            lbosOut.write(b);
        }

        lbisIn.close();
        lbosOut.close();
    }

    public String getFldType(String pstrFldKind,String pstrFldLen){
        String lstrRetValue=null;

        if(pstrFldKind.equals("N")){//數字
            lstrRetValue=(pstrFldLen==null || pstrFldLen.trim().equals("") || pstrFldLen.trim().indexOf("0")<0 ? "long" : "double");
        }
        else if(pstrFldKind.equals("D")){//日期
            lstrRetValue="String";
        }
        else{
            lstrRetValue="String";
        }

        return lstrRetValue;
    }
    
    public Hashtable<String,Hashtable<String,Object>> getFieldsByTable(String pstrDbfNO) throws Exception{
    	try{
    		return gqbnDAO.hashtableSQL("select fld_no,fld_name,fld_kind,wide from wkf_layout where dbf_no='" + pstrDbfNO + "'");
    	}
    	catch(Exception e){
    		e.printStackTrace();
    		throw new Exception(e);
    	}
    }

    public String getParseSyntax(String pstrFldKind,String pstrWideDec){
        String lstrFldType=getFldType(pstrFldKind,pstrWideDec);
        String lstrRetValue=null;

        if(lstrFldType.equals("double")){
            lstrRetValue="Double.parseDouble";
        }
        else if(lstrFldType.equals("long")){
            lstrRetValue="Long.parseLong";
        }
        else if(lstrFldType.equals("String")){
            if(pstrFldKind.equals("D")){
                lstrRetValue = "PublicFunction.getTimestempDate";
            }
            else{
                lstrRetValue = "String.valueOf";
            }
        }

        return lstrRetValue;
    }

    public String getParseToObjectSyntax(String pstrFldKind,String pstrWideDec){
        String lstrFldType=getFldType(pstrFldKind,pstrWideDec);
        String lstrRetValue=null;

        if(lstrFldType.equals("double")){
            lstrRetValue="Double.valueOf";
        }
        else if(lstrFldType.equals("long")){
            lstrRetValue="Long.valueOf";
        }
        else if(lstrFldType.equals("String")){
            lstrRetValue="String.valueOf";
        }

        return lstrRetValue;
    }

    protected void setBaseVarible(String pstrPrgNO) throws Exception{
        setPrgInfo(pstrPrgNO);
    }

    private void setPrgInfo(String pstrPrgNO) throws Exception{
        Hashtable<String,Object> lhtPrgInfo=null;
        StringBuffer lstbSQL=new StringBuffer();

        try{
            if(pstrPrgNO==null || pstrPrgNO.trim().equals("")){
                throw new Exception("parameter pstrPrgNO is null");
            }

            lstbSQL.append("select flow_yn,prg_kind,flow_code from wkf_prg where prg_no='");
            lstbSQL.append(pstrPrgNO);
            lstbSQL.append("'");

            lhtPrgInfo=gqbnDAO.readSingleRowData(lstbSQL.toString());

            this.gblnFlowYN=lhtPrgInfo.get("FLOW_YN").toString().toUpperCase().equals("Y");
            this.gstrPrgKind=lhtPrgInfo.get("PRG_KIND").toString().toUpperCase();
            this.gstrFlowCode=lhtPrgInfo.get("FLOW_CODE").toString().toUpperCase();
        }
        catch(Exception e){
            throw new Exception(e.toString() + " in SwdBase.setBaseVarible(String)");
        }
        finally{
            if(lhtPrgInfo!=null){
                lhtPrgInfo.clear();
                lhtPrgInfo=null;
            }
        }
    }
}
